package com.zeroext.sys.util;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.TreeMap;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.zeroext.common.util.JsonUtil;
import com.zeroext.common.util.JsonWapper;
import com.zeroext.sys.entity.MenuBean;

public class MenuLoadUtil {

    private Document doc;
    private InputStream is;
    private String relatyPath = "menu.xml";
    private static TreeMap<String, MenuBean> menuMap = new TreeMap<String, MenuBean>();
    private static boolean isBuild = false;
    private static TreeMap<String,String> defaultQuickMenu = new TreeMap<String,String>();

    public MenuLoadUtil() throws ParserConfigurationException, SAXException,
            IOException {
        if (isBuild == false) {
            is = getClass().getClassLoader().getResourceAsStream(relatyPath);
            // is = new FileInputStream(... + File.separator+"menu.xml");
            // is = new FileInputStream("d:/menu.xml");
            DocumentBuilderFactory domfac = DocumentBuilderFactory
                    .newInstance();
            DocumentBuilder dombuilder = domfac.newDocumentBuilder();
            doc = dombuilder.parse(is);
            buildMenuMap();
        }
    }
    
    public String getJson(String webContext){
        String json = "";
        try {
            json = this.getMenuJson(webContext);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return json;
    }
    
 // 2, get filter map --> iterate --> create panel --> return
    private String getMenuJson(String webContext) throws Exception {
        String json = "";
        String data = "";

        TreeMap<String, MenuBean> menuMap = new MenuLoadUtil().getMenuMap();
        Iterator<String> it = menuMap.keySet().iterator();
        int i = 0;
        while (it.hasNext()) {
            String key = it.next().toString();
            // for example : menu.event
            if (key.split("\\.").length == 2 && key.startsWith("menu")) {
                MenuBean menu = menuMap.get(key);
                if (menu == null) {
                    continue;
                }
                String panel = this.createPanel(menu,webContext);
                data += panel + ",";
                i++;
            }
        }
        data = JsonUtil.deleteLastComma(data);
        json = JsonUtil.encodeJson(data, i + "");
        return json;
    }
    
    // 3 create panel
    private String createPanel(MenuBean menu,String webContext) {
        String panel = "";
        /**
         * var treeLoader = new Ext.tree.TreeLoader({ url :
         * '/menu_getSubNodes.action', baseAttrs : { uiProvider :
         * Ext.ux.TreeCheckNodeUI } }); var stateRoot = new
         * Ext.tree.AsyncTreeNode({ id : '/root', text : 'notVisiableRoot',
         * loader : treeLoader, expanded : true // checked : true });
         */
        // buildLoader
        String loaderConfig = "";
        String url = webContext+"/menu_getSubNodes.action";
        loaderConfig = JsonUtil.encodeRecord(loaderConfig, "url", url + "");
        String loader = "new Ext.tree.TreeLoader({"
                + JsonUtil.deleteLastComma(loaderConfig) + "})";
        // buildRoot
        String rootConfig = "";
        rootConfig = JsonUtil
                .encodeRecord(rootConfig, "id", menu.getKey() + "");
        rootConfig = JsonUtil.encodeRecord(rootConfig, "text", "notVisibleRoot"
                + "");
        rootConfig = JsonUtil.encodeRecordWithoutquotation(rootConfig,
                "expanded", "true" + "");
        rootConfig = JsonUtil.encodeRecordWithoutquotation(rootConfig,
                "loader", loader + "");
        String root = "new Ext.tree.AsyncTreeNode({"
                + JsonUtil.deleteLastComma(rootConfig) + "})";

        // build menu_panel
        String panelConfig = "";
        panelConfig = JsonUtil.encodeRecord(panelConfig, "id", menu.getId()
                + "");
        panelConfig = JsonUtil.encodeRecordWithoutquotation(panelConfig,
                "title", "'" + menu.getTitle() + "'");
        panelConfig = JsonUtil.encodeRecordWithoutquotation(panelConfig,
                "rootVisible", "false" + "");
        panelConfig = JsonUtil.encodeRecordWithoutquotation(panelConfig,
                "root", root);
        panelConfig = JsonUtil.encodeRecordWithoutquotation(panelConfig,
                "autoScroll", "true" + "");
        if (StringUtils.isNotEmpty(menu.getIcon())) {
            panelConfig = JsonUtil.encodeRecord(panelConfig, "icon", menu
                    .getIcon());
        }
        panelConfig = JsonUtil.deleteLastComma(panelConfig);

        panel = "new Ext.tree.TreePanel({"
                + JsonUtil.deleteLastComma(panelConfig) + "})";

        return panel;
    }

    private void buildMenuMap() {
        Element root = this.doc.getDocumentElement();
        addMenu(root);
        isBuild = true;
    }

    private void addMenu(Element node) {
        NodeList childMenus = node.getChildNodes();
        for (int i = 0; i < childMenus.getLength(); i++) {
            Node childMenu = childMenus.item(i);
            if (childMenu.getNodeType() == Node.ELEMENT_NODE) {
                String key = childMenu.getAttributes().getNamedItem("key")
                        .getNodeValue();
                Node idNode = childMenu.getAttributes().getNamedItem("id");
                String id = idNode == null ? null : idNode.getNodeValue();

                Node urlNode = childMenu.getAttributes().getNamedItem("url");
                String url = urlNode == null ? null : urlNode.getNodeValue();

                Node iconNode = childMenu.getAttributes().getNamedItem("icon");
                String icon = iconNode == null ? null : iconNode.getNodeValue();

                Node titleNode = childMenu.getAttributes().getNamedItem("title");
                String title = titleNode == null ? null : titleNode.getNodeValue();
                
                Node typeNode = childMenu.getAttributes().getNamedItem("type");
                String type = typeNode == null ? "item" : typeNode.getNodeValue();
                
                Node rightNode = childMenu.getAttributes().getNamedItem("right");
                String right = rightNode == null ? null : rightNode.getNodeValue();
                
                Node qMenuNode =  childMenu.getAttributes().getNamedItem("qMenu");
                if(qMenuNode!=null && defaultQuickMenu.size()<=5){
                    String order = qMenuNode.getNodeValue();
                    if(StringUtils.isNotEmpty(order)){
                        defaultQuickMenu.put(order, key);
                    }
                }
                MenuBean MenuBean = new MenuBean(key, id, url, icon,
                        title, type, right, i,true,0,0);
                menuMap.put(key, MenuBean);
                addMenu((Element) childMenu);
            }
        }
    }

    public MenuBean getMenu(String key) {
        return menuMap.get(key);
    }

    public TreeMap<String, MenuBean> getMenuMap() {
        return menuMap;
    }
    
    public String getDeskJson(String webContext)throws Exception{
        JsonWapper jw = new JsonWapper();
        int i=0;
        for(String key : menuMap.keySet()){
            MenuBean menu = menuMap.get(key);
            if (menu == null) {
                continue;
            }
            if(!menu.isQuickMenu()){
                continue;
            }
            JSONObject jo = jw.nextItem();
            jo.put("appWidth", menu.getWidth());
            jo.put("appHeight", menu.getHeight());
            jo.put("appTitle", menu.getTitle());
            jo.put("appIcon", webContext + menu.getIcon());
            jo.put("targetUrl", webContext + menu.getUrl());
            jo.put("appId", menu.getId());
            jo.put("appKey", menu.getKey());
            jw.endItem(jo);
            i++;
        }
        System.out.println(jw.getStoreJson(i));
        return jw.getStoreJson(i);
    }
    
    public String getExtUIMenuJson(){
        String json = "";
        List<JSONObject> models = new ArrayList<JSONObject>();
        JSONObject parent = null;
        for(String key : menuMap.keySet()){
            MenuBean bean = menuMap.get(key);
            String type = bean.getType();
            if(MenuBean.TYPE_MODEL.equals(type)){
                JSONObject modelJo = encodeMenuObj(bean);
                models.add(modelJo);
                parent = modelJo;
            }else if(MenuBean.TYPE_GROUP.equals(type)){
                JSONObject groupJo = encodeMenuObj(bean);
                addChildMenu(parent, groupJo);
                parent = groupJo;
            }else if(MenuBean.TYPE_ITEM.equals(type)){
                JSONObject itemJo = encodeMenuObj(bean);
                addChildMenu(parent, itemJo);
            }
        }
        JSONArray ja = JSONArray.fromObject(models);
        json = ja.toString();
        return json;
    }
    
    @SuppressWarnings("unchecked")
    private void addChildMenu(JSONObject parent,JSONObject child){
        JSONArray childrent = null;
        if(!parent.containsKey("childrent")){
            childrent = new JSONArray();
            parent.put("childrent", childrent);
        }else{
            childrent = parent.getJSONArray("childrent");
        }
        childrent.add(child);
        parent.put("childrent", childrent);
    }
    
    private JSONObject encodeMenuObj(MenuBean bean){
        JSONObject jo = new JSONObject();
        jo.put("id", bean.getIcon());
        jo.put("key", bean.getKey());
        jo.put("type", bean.getType());
        jo.put("icon", bean.getIcon());
        jo.put("title", bean.getTitle());
        jo.put("right", bean.getRight());
        if(MenuBean.TYPE_ITEM.equals(bean.getType())){
            jo.put("url", bean.getUrl());
        }
        return jo;
    }

    public static void main(String[] args)throws Exception{
        String json = new MenuLoadUtil().getExtUIMenuJson();
        System.out.println(json);
    }
    
    public TreeMap<String,String> getDefaultQMenu(){
        return defaultQuickMenu;
    }
}
